<template>
  <div id="global-uploader">
    <div>
      <el-button @click="handleClick">选择图片文件11</el-button>
    </div>
    <uploader
      ref="uploader"
      class="uploader-app"
      :options="options"
      :fileStatusText="fileStatusText"
      :auto-start="false"
      @file-added="onFileAdded"
      @file-success="onFileSuccess"
      @file-progress="onFileProgress"
      @file-error="onFileError"
    >
      <uploader-unsupport />
      <uploader-drop>
        <p>Drop files here to upload</p>
      </uploader-drop>
      <uploader-btn id="global-uploader-btn" ref="uploadBtn" :attrs="attrs">选择图片文件</uploader-btn>
      <!-- <uploader-btn :directory="true">选择文件夹</uploader-btn> -->
      <!--文件列表-->
      <uploader-list v-show="panelShow">
        <div slot-scope="props" class="file-panel" :class="{'collapse': collapse}">
          <div class="file-title">
            <h2>文件列表</h2>
            <div class="operate">
              <el-button type="text" :title="collapse ? '展开':'折叠' " @click="fileListShow">
                <i class="iconfont" :class="collapse ? 'inuc-fullscreen': 'inuc-minus-round'"></i>
              </el-button>
              <el-button type="text" title="关闭" @click="close">
                <i class="iconfont icon-close"></i>
              </el-button>
            </div>
          </div>
          <div class="file-list">
            <div v-for="file in props.fileList" :key="file.id">
              <uploader-file ref="files" :class="'file_' + file.id" :file="file" :list="true" />
              <!--<uploader-file :file="file" :list="true" ref="uploaderFile" :pauseFlag="pauseFlag">
                <template slot-scope="props">
                  <div class="file-box">
                    <p class="fileNameBox">
                      <span class="fileIcon"></span>
                      {{file.name}}
                    </p>
                    <p class="fileProgressBox">
                      <el-progress
                        class="progressLength"
                        :percentage="parseInt((props.progress.toFixed(2))*100-1<0?0:(props.progress.toFixed(2))*100-1)"
                      ></el-progress>
                      <span
                        :class="{statusBtn:!pauseFlag,resumeBtn:pauseFlag}"
                        class="progressBtn"
                        @click="handlePause(file,file.resourceId)"
                      >stop</span>
                      <span class="cancelBtn progressBtn" @click="handleRemove(file,file.resourceId)">del</span>
                    </p>
                    <p class="fileInfoBox">
                      <span class="fileInfoItem">速度：{{pauseFlag? 0: props.formatedAverageSpeed}}</span>
                      <span
                        class="fileInfoItem"
                      >已上传：{{(parseFloat(props.formatedSize)*props.progress).toFixed(1)}}/{{props.formatedSize}}</span>
                      <span
                        class="fileInfoItem"
                      >剩余时间：{{pauseFlag? 0: props.formatedTimeRemaining}}</span>
                    </p>
                  </div>
                </template>
              </uploader-file>-->
            </div>
            <div v-if="!props.fileList.length" class="no-file"><i class="iconfont icon-empty-file"></i>暂无待上传文件</div>
          </div>
        </div>
      </uploader-list>
    </uploader>
  </div>
</template>

<script>
// import ElImageViewer from 'element-ui/packages/image/src/image-viewer';
// 参考资料
/**
 * 参考资料
 * https://github.com/simple-uploader/Uploader
 * https://github.com/simple-uploader/vue-uploader
 * 0. https://www.cnblogs.com/xiahj/p/vue-simple-uploader.html
 * 1. https://github.com/lrfbeyond/fast-uploader
 * 2. https://github.com/shady-xia/Blog/tree/master/vue-simple-uploader
 *    https://www.helloweba.net/javascript/632.html
 * 3. https://github.com/pseudo-god/vue-simple-upload
 */

export default {
  name: 'UploadTest',
  components: {},
  data() {
    return {
      options: {
        target: 'http://xxxxx/xx', // 目标上传 URL
        chunkSize: '2048000', // 分块大小
        fileParameterName: 'file', // 上传文件时文件的参数名，默认file
        maxChunkRetries: 3, // 最大自动失败重试上传次数
        testChunks: true, // 是否开启服务器分片校验
        // 服务器分片校验函数，秒传及断点续传基础
        checkChunkUploadedByResponse: function(chunk, message) {
          const objMessage = JSON.parse(message)
          if (objMessage.skipUpload) {
            this.statusTextMap.success = '秒传文件'
            return true
          }
          return (objMessage.uploaded || []).indexOf(chunk.offset + 1) >= 0
        },
        headers: {
          // 在header中添加的验证，请根据实际业务来
          'access-token': 'abcd1234'
        },
        query() {}
      },
      // allowDuplicateUploads
      attrs: {
        // 接受的文件类型，形如['.png', '.jpg', '.jpeg', '.gif', '.bmp']
        accept: 'image/*'
      },
      panelShow: false, // 选择文件后，展示上传panel
      collapse: false,
      pauseFlag: false,
      statusTextMap: {
        success: '上传成功',
        error: '上传出错了',
        uploading: '上传中...',
        paused: '暂停',
        waiting: '等待中...',
        cmd5: '计算md5...'
      },
      fileStatusText: (status) => {
        return this.statusTextMap[status]
      }
    }
  },
  computed: {
    // Uploader实例
    uploader() {
      return this.$refs.uploader.uploader
    }
  },
  watch: {},
  mounted() {
    // Bus.$on('openUploader', query => {
    //   this.params = query || {}
    //   if (this.$refs.uploadBtn) {
    //     $('#global-uploader-btn').click()
    //   }
    // })
  },
  destroyed() {
    // Bus.$off('openUploader')
  },
  methods: {
    handlePause() {
      // todo
    },
    handleRemove() {
      // todo
    },
    handleClick() {
      if (this.$refs.uploadBtn) {
        const oDiv = document.getElementById('global-uploader-btn')
        oDiv.click()
      }
    },
    onFileAdded(file) {
      console.log('file===', file)
      this.panelShow = true
      // this.computeMD5(file)
      // Bus.$emit('fileAdded')
    },
    onFileProgress(rootFile, file, chunk) {
      console.log('onFileProgress===', rootFile, file, chunk)
      console.log(`上传中 ${file.name}，chunk：${chunk.startByte / 1024 / 1024} ~ ${chunk.endByte / 1024 / 1024}`)
    },
    onFileSuccess(rootFile, file, response, chunk) {
      console.log('onFileSuccess===', rootFile, file, response, chunk)
      const res = JSON.parse(response)
      // 服务器自定义的错误（即虽返回200，但是是错误的情况），这种错误是Uploader无法拦截的
      if (!res.result) {
        this.$message({ message: res.message, type: 'error' })
        // 文件状态设为“失败”
        this.statusSet(file.id, 'failed')
        return
      }
      // 如果服务端返回需要合并
      if (res.needMerge) {
        // 文件状态设为“合并中”
        this.statusSet(file.id, 'merging')
        // api.mergeSimpleUpload({
        //   tempName: res.tempName,
        //   fileName: file.name,
        //   ...this.params
        // }).then(res => {
        //   // 文件合并成功
        //   Bus.$emit('fileSuccess')
        //   this.statusRemove(file.id)
        // }).catch(e => {})
        // 不需要合并
      } else {
        // Bus.$emit('fileSuccess')
        console.log('上传成功')
      }
    },
    onFileError(rootFile, file, response) {
      file.cancel()
      this.$message({
        message: response,
        type: 'error'
      })
    },
    /**
       * 计算md5，实现断点续传及秒传
       * @param file
       */
    // computeMD5(file) {
    //   const fileReader = new FileReader()
    //   const time = new Date().getTime()
    //   const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
    //   let currentChunk = 0
    //   const chunkSize = 10 * 1024 * 1000
    //   const chunks = Math.ceil(file.size / chunkSize)
    //   const spark = new SparkMD5.ArrayBuffer()
    //   // 文件状态设为"计算MD5"
    //   this.statusSet(file.id, 'md5')
    //   file.pause()
    //   loadNext()
    //   fileReader.onload = e => {
    //     spark.append(e.target.result)
    //     if (currentChunk < chunks) {
    //       currentChunk++
    //       loadNext()
    //       // 实时展示MD5的计算进度
    //       this.$nextTick(() => {
    //         $(`.myStatus_${file.id}`).text('校验MD5 ' + ((currentChunk / chunks) * 100).toFixed(0) + '%')
    //       })
    //     } else {
    //       const md5 = spark.end()
    //       this.computeMD5Success(md5, file)
    //       console.log(`MD5计算完毕：${file.name} \nMD5：${md5} \n分片：${chunks} 大小:${file.size} 用时：${new Date().getTime() - time} ms`)
    //     }
    //   }
    //   fileReader.onerror = function() {
    //     this.error(`文件${file.name}读取出错，请检查该文件`)
    //     file.cancel()
    //   }
    //   function loadNext() {
    //     const start = currentChunk * chunkSize
    //     const end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize
    //     fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end))
    //   }
    // },
    computeMD5Success(md5, file) {
      // 将自定义参数直接加载uploader实例的opts上
      Object.assign(this.uploader.opts, {
        query: {
          ...this.params
        }
      })
      file.uniqueIdentifier = md5
      file.resume()
      this.statusRemove(file.id)
    },
    fileListShow() {
      this.collapse = !this.collapse
    },
    close() {
      this.uploader.cancel()
      this.panelShow = false
    },
    /**
       * 新增的自定义的状态: 'md5'、'transcoding'、'failed'
       * @param id
       * @param status
       */
    statusSet(id, status) {
      // const statusMap = {
      //   md5: {
      //     text: '校验MD5',
      //     bgc: '#fff'
      //   },
      //   merging: {
      //     text: '合并中',
      //     bgc: '#e2eeff'
      //   },
      //   transcoding: {
      //     text: '转码中',
      //     bgc: '#e2eeff'
      //   },
      //   failed: {
      //     text: '上传失败',
      //     bgc: '#e2eeff'
      //   }
      // }
      // this.$nextTick(() => {
      //   $(`<p class="myStatus_${id}"></p>`).appendTo(`.file_${id} .uploader-file-status`).css({
      //     'position': 'absolute',
      //     'top': '0',
      //     'left': '0',
      //     'right': '0',
      //     'bottom': '0',
      //     'zIndex': '1',
      //     'backgroundColor': statusMap[status].bgc
      //   }).text(statusMap[status].text)
      // })
    },
    statusRemove(id) {
      // this.$nextTick(() => {
      //   $(`.myStatus_${id}`).remove()
      // })
    },
    error(msg) {
      this.$notify({
        title: '错误',
        message: msg,
        type: 'error',
        duration: 2000
      })
    }
  }
}
</script>

<style scoped lang="scss">
  #global-uploader {
    .uploader-app {
      width: 100%;
    }
    .file-panel {
      width: 600px;
      position: fixed;
      bottom: 10px;
      right: 10px;
      background-color: #fff;
      border: 1px solid #e2e2e2;
      border-radius: 7px 7px 0 0;
      box-shadow: 0 0 10px rgba(0, 0, 0, .2);
      .file-title {
        display: flex;
        padding: 0 10px;
        border-bottom: 1px solid #ddd;
        .operate {
          flex: 1;
          text-align: right;
        }
      }
      .file-list {
        position: relative;
        height: 240px;
        overflow-x: hidden;
        overflow-y: auto;
        background-color: #fff;
        > li {
          background-color: #fff;
        }
        .file-box {
          display: flex;
        }
      }
      &.collapse {
        .file-title {
          background-color: #E7ECF2;
        }
      }
    }
    .no-file {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      font-size: 16px;
    }
    /deep/.uploader-file-icon {
      &:before {
        content: '' !important;
      }
      &[icon=image] {
        background: url(../../assets/commodity/image-icon.png);
      }
      &[icon=video] {
        background: url(../../assets/commodity/video-icon.png);
      }
      &[icon=document] {
        background: url(../../assets/commodity/text-icon.png);
      }
    }
    /deep/.uploader-file-actions > span {
      margin-right: 6px;
    }
  }
  /* 隐藏上传按钮 */
  #global-uploader-btn {
    position: absolute;
    clip: rect(0, 0, 0, 0);
  }
</style>
